package com.fingard.dsp.bank.directbank.fubon01;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptData;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptDataHelper;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directConfig.ReceiptProConfig;
import com.fingard.dsp.bank.directbank.bankInterface.IReceiptPro;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.ReqQryReceipt;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.RetAtsReceipt;
import com.fingard.dsp.task.command.SyncReceipt;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;
import com.fingard.util.SmbFileUtil;

import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

public class FUBON01ReceiptPro extends FUBON01Base implements IReceiptPro {
    @Override
    public RetAtsReceipt qryReceiptOneDay(ReceiptProConfig pConfig, ReqQryReceipt pReqReceipt, Date pOneDay) throws Exception {
        ReceiptDataHelper receiptHelper = new ReceiptDataHelper(pReqReceipt.reqHeader.tenant, pOneDay);//回单数据保存类，分区分表
        try {
            //1.发送post请求到银行,单笔和批量都查询,查回数据存入数据库
            WriteBankLogLn2("开始查询" + pReqReceipt.actNum + "," + Format.Date10Format.format(pOneDay) + "回单数据...");
            getRecceiptData(pReqReceipt, pOneDay, receiptHelper);
            WriteBankLogLn(pReqReceipt.actNum + "," + Format.Date10Format.format(pOneDay) + "回单数据查询完成，开始下载PDF文件");

            //2.根据查询的回单入库数据，下载回单文件
            ArrayList<String> list = receiptHelper.getIstNbrList(pReqReceipt.actNum, pOneDay);
            WriteBankLogLn(pReqReceipt.actNum + "，" + Format.Date10Format.format(pOneDay) + "需要进行下载的回单文件个数：" + list.size());
            if (list.size() <= 0) {
                return null;
            }
            downPDFFile(pConfig, pReqReceipt, pOneDay, list);
        } catch (Exception ex) {
            this.WriteBankLogLn(ex);
        } finally {
            if (receiptHelper != null) {
                receiptHelper.close();
            }
        }
        SyncReceipt.resetDelayCounter();//同步任务重新计数延时
        return null;
    }

    public void getRecceiptData(ReqQryReceipt pReqReceipt, Date pOneDay, ReceiptDataHelper receiptHelper) throws Exception {
        String postDate = Format.Date10Format.format(pOneDay);
        try {
            String[] isSingleList = {"Y", "N"};
            for (String isSingle : isSingleList) {
                String isSinleCN = isSingle.equals("Y") ? "单笔" : "批量";
                WriteBankLogLn2("开始查询账号:" + pReqReceipt.actNum + ",日期：" + postDate + "," + isSinleCN + "的回单数据...");
                JSONObject reqJson = new JSONObject();
                reqJson.put("Acct_No", pReqReceipt.actNum);//客户账号，完全匹配 必填
                reqJson.put("Certificate_From_Date", postDate);//凭证产生开始时间 yyyy-MM-dd 必填
                reqJson.put("Certificate_To_Date", postDate);//凭证产生结束时间 yyyy-MM-dd 必填
                reqJson.put("Is_Single", isSingle);//？？？是否单笔标志 Y/N 单笔or 批量 必填
                reqJson.put("Ref_No", "");//核心交易流水号 非必填

                String[] tmpStrRet = sendToBank2(reqJson.toJSONString());
                if (tmpStrRet[0].length() == 0) {
                    JSONObject resultObj = JSONObject.parseObject(tmpStrRet[1]);
                    //state：返回状态，1代表成功，反之为0，msg是失败提示
                    String state = resultObj.getString("state");
                    String msg = resultObj.getString("msg");
                    if (state.equals("1")) {
                        JSONArray dataArray = resultObj.getJSONArray("data");
                        for (int i = 0; i < dataArray.size(); i++) {
                            JSONObject data = dataArray.getJSONObject(i);
                            ReceiptData rcpt = new ReceiptData();
                            String trsdate = data.getString("trsdate");//如：10/30/2018 00:00:00
                            Date date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(trsdate);
                            trsdate = Format.Date10Format.format(date);
                            if (!postDate.equals(trsdate)) {
                                WriteBankLogLn("回单凭证号:" + data.getString("receiptid") + " 数据的日期" + trsdate + "与预期" + postDate + "不符");
                            } else {
                                //存入电子回单数据到数据库
                                String filePathAndName = data.getString("path") + data.getString("receiptid") + ".pdf";
                                rcpt.localFile = filePathAndName.replaceAll("\\\\", "/");//先存入查询回来的地址，下载成功后更新为ATS-DSP服务文件地址
//                                rcpt.localFile = filePathAndName;//先存入查询回来的地址，下载成功后更新为ATS-DSP服务文件地址
                                rcpt.ownAct = pReqReceipt.actNum;
                                rcpt.bank = "787";
                                rcpt.srcSys = "FUBON01";
                                rcpt.istNbr = data.getString("receiptid");//对应凭证的代码
                                rcpt.receiptNo = rcpt.istNbr;
                                rcpt.bnkSeqNo = rcpt.receiptNo;
                                rcpt.busDate = Integer.parseInt(postDate.replaceAll("-", ""));
                                rcpt.busRef = data.getString("receiptid");
//                            String cdFlag = text[29];
//                            if ("C".equals(cdFlag)) {
//                                rcpt.moneyWay = "2";
//                            } else if ("D".equals(cdFlag)) {
//                                rcpt.moneyWay = "1";
//                            }
                                rcpt.amount = new BigDecimal(data.getString("amount"));
//                            rcpt.voucherNo = text[9];
//                            rcpt.oppActNum = text[17];
//                            rcpt.oppActName = text[19];
                                rcpt.cur = convertCurToATS(data.getString("ccy"));
                                int inRe = receiptHelper.insertIfNotExist(rcpt, true);
                                WriteBankLogLn2("回单编号：" + rcpt.receiptNo + "写入数据库，影响行数：" + inRe);
                            }
                        }
                    } else {
                        WriteBankLogLn(pReqReceipt.actNum + "," + postDate + ",Is_Single=" + isSingle + ",回单数据查询失败：" + msg);
                    }
                } else {
                    WriteBankLogLn(pReqReceipt.actNum + "," + postDate + ",Is_Single=" + isSingle + "回单数据查询失败：" + tmpStrRet[0]);
                }
            }
        } catch (
                Exception ex) {
            this.WriteBankLogLn(ex);
        }
    }

    public void downPDFFile(ReceiptProConfig pConfig, ReqQryReceipt pReqReceipt, Date pOneDay, ArrayList<String> list) throws Exception {
        ReceiptDataHelper receiptHelper = new ReceiptDataHelper(pReqReceipt.reqHeader.tenant, pOneDay);
        String qryDay8 = Format.Date8Format.format(pOneDay);
        String receiptDownType = getBankConfig().getValueAsString("receiptDownType");
        String localpath = pConfig.getSaveSubDir(pReqReceipt.reqHeader, pOneDay) + File.separator + qryDay8;
        FileHelper.mkdirsIfNotExists(localpath);//判断目录是否存在不存在就创建
        String filePathAndName = "";

        //根据传入list：查询回来需要下载的回单编号获取文件下载路径（名）下载
        for (int i = 0; i < list.size(); i++) {
            boolean downloadKey = false;//下载文件是否成功
            ReceiptData receiptData = new ReceiptData();
            receiptData = receiptHelper.loadFromDbByIstNbr(pReqReceipt.actNum, list.get(i));
            filePathAndName = receiptData.localFile;

            if ("sftp".equals(receiptDownType)) {
                //Sftp方式
                SftpPortClient sftpPortClient = null;
                try {
                    FtpSet ftpSet = bankFront.getFtpSet("receipt");
                    ftpSet.downDir = StringHelper.trimEnd(ftpSet.downDir, "/") + "/";
                    WriteBankLogLn("SFTP下载地址" + ftpSet.serverIP + ":" + ftpSet.port);

                    sftpPortClient = new SftpPortClient(ftpSet);
                    WriteBankLogLn("下载到本地目录为：" + localpath);
                    WriteBankLogLn("sftp目录下文件名为：" + filePathAndName);
                    FtpReceiver ftpReceiver = sftpPortClient.downloadFileByName("", localpath, filePathAndName);
                    if (ftpReceiver.isCompleted) {
                        WriteBankLogLn("下载成功，下载路径为：" + localpath + "文件名为" + filePathAndName);
                    } else {
                        WriteBankLogLn("下载失败，文件名为" + filePathAndName);
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                    WriteBankLogLn(ex);
                } finally {
                    if (sftpPortClient != null) {
                        sftpPortClient.disconnect();
                    }
                }
            } else if ("ftp".equals(receiptDownType)) {
                FtpSet ftpSet = bankFront.getFtpSet("receipt");
                FtpPortClient client = new FtpPortClient(ftpSet);
                FtpReceiver ftpReceiver = client.downloadFile(filePathAndName, localpath);
                if (!ftpReceiver.isCompleted) {
                    WriteBankLogLn(ftpReceiver.connMsg);
                } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
                    WriteBankLogLn("下载失败");
                } else {
                    WriteBankLogLn("下载成功");
                }
            } else if ("smb".equals(receiptDownType)) {
                //共享目录方式
                String subStringPath = getBankConfig().getValueAsString("subStringSmbPath");
                //因为富邦返回的是一个绝对路径，要把共享的文件夹前面的父路径给截取掉
                filePathAndName = filePathAndName.substring(filePathAndName.lastIndexOf(subStringPath) + subStringPath.length() + 1);
                WriteBankLogLn("富邦华一PDF回单文件下载目录：" + localpath + "，下载文件地址：" + filePathAndName);

                if (StringHelper.hasAnyChar(bankFront.bkTransFolder)) {
                    if (bankFront.bkTransFolder.startsWith("smb://")) {
                        StringBuilder smbSb = new StringBuilder();
                        //因为富邦这个共享目录有子文件夹，本地文件路径下载成功后会将子路径加在localpath后，所以做一下控制
                        String filePath = filePathAndName.substring(0, filePathAndName.lastIndexOf("/"));
                        String fileName = filePathAndName.substring(filePathAndName.lastIndexOf("/") + 1);
                        String smbFilePath = StringHelper.trimEndFileSp(bankFront.bkTransFolder) + "/" + filePath;
                        SmbFileUtil.smbDownloadInChar(localpath, smbFilePath, fileName, smbSb);
                        if (smbSb.length() != 0) {
                            downloadKey = false;
                            WriteBankLogLn("共享目录下载回单PDF文件:" + filePathAndName + "失败：" + smbSb.toString());
                        } else {
                            downloadKey = true;
                            WriteBankLogLn("共享目录下载回单PDF文件:" + filePathAndName + "成功,本地目录：" + localpath);
                        }
                    } else {
                        String srcFilePath = StringHelper.trimEndFileSp(bankFront.bkTransFolder) + File.separator + filePathAndName;
                        String fileName = filePathAndName.substring(filePathAndName.lastIndexOf(File.separator) + 1);
                        FileHelper.copyFile(srcFilePath, localpath + File.separator + fileName);
                        if (!new File(localpath + File.separator + fileName).exists()) {
                            downloadKey = false;
                            WriteBankLogLn("共享盘下载回单PDF文件:" + srcFilePath + "失败");
                        } else {
                            downloadKey = true;
                            WriteBankLogLn("共享盘下载回单PDF文件:" + srcFilePath + "成功,本地目录：" + localpath);
                        }
                    }
                } else {
                    throw new Exception("请配置BankFront.xml银行前置机回单目录");
                }
            } else {
                //本地直接复制 linux挂载
                String linuxLocalPath = getBankConfig().getValueAsString("linuxReceiptLocationPath");
                //因为富邦返回的是一个绝对路径，要把共享的文件夹未挂载前面的父路径给截取掉
                String subStringPath = getBankConfig().getValueAsString("subStringSmbPath");
                filePathAndName = filePathAndName.substring(filePathAndName.lastIndexOf(subStringPath) + subStringPath.length() + 1);
                linuxLocalPath = StringHelper.trimEndFileSp(linuxLocalPath) + "/" + filePathAndName;
                if (!new File(linuxLocalPath).exists()) {
                    downloadKey = false;
                    WriteBankLogLn("本地直接复制回单PDF文件:" + linuxLocalPath + "失败:源文件不存在");
                } else {
                    String fileName = filePathAndName.substring(filePathAndName.lastIndexOf("/") + 1);
                    FileHelper.copyFile(linuxLocalPath, localpath + File.separator + fileName);
                    if (!new File(localpath + File.separator + fileName).exists()) {
                        downloadKey = false;
                        WriteBankLogLn("本地直接复制回单PDF文件:" + filePathAndName + "失败");
                    } else {
                        downloadKey = true;
                        WriteBankLogLn("本地直接复制回单PDF文件:" + filePathAndName + "成功,本地目录：" + localpath);
                    }
                }
            }
            //将DSP服务下载到本地保存回单的地址，根据查询回单数据的凭证号存入数据库
            String fileName = filePathAndName.substring(filePathAndName.lastIndexOf("/"), filePathAndName.length());
            getPdfFiles(pConfig, pReqReceipt, pOneDay, StringHelper.trimEndFileSp(localpath) + fileName, receiptData.istNbr, downloadKey);
        }
    }


    /**
     * 提取下载的pdf地址
     */
    protected void getPdfFiles(ReceiptProConfig pConfig, ReqQryReceipt pReqReceipt, Date pOneDay, String pReceiptDir, String istNbr, boolean downloadKey) {
        ReceiptDataHelper receiptHelper = null;//回单数据保存类，分区分表
        try {
            receiptHelper = new ReceiptDataHelper(pReqReceipt.reqHeader.tenant, pOneDay);
            File receiptDir = new File(pReceiptDir);

            //数据库中存储的路径是相对pConfig.localSaveMainDir的相对路径
            String relativePath = StringHelper.getRelativePath(receiptDir.getAbsolutePath(), pConfig.localSaveMainDir).trim();
            if (downloadKey) {
                int inRe = receiptHelper.updateDownState(pReqReceipt.actNum, istNbr, relativePath, receiptDir.getName(), "2");
                if (inRe > 0) {
                    WriteBankLogLn("回单编号" + istNbr + "，文件" + receiptDir.getName() + "下载成功，重命名成功，更新影响行数：" + inRe);
                }
            }
        } catch (Exception ex) {
            this.WriteBankLogLn(ex);
        } finally {
            if (receiptHelper != null) {
                receiptHelper.close();
            }
        }
    }
}
